package com.yunwaikeji.gy_tool_library.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.yunwaikeji.gy_tool_library.R;
import com.yunwaikeji.gy_tool_library.utils.display.GYDisplayUtils;
import com.yunwaikeji.gy_tool_library.view.GYImageView;

public class GYSignView extends GYImageView {
    private static final String TAG = "GYSignView";
    private Paint mPathPaint;
    private Paint mBitmapPaint;
    private Canvas mCanvas;
    private Path mPath;
    private Bitmap mBitmap;
    private int paintWidthPx;

    private boolean allowPaint = true;//是否可以写

    private boolean painted = false;//是否已经写了

    public GYSignView(@NonNull Context context) {
        super(context);
        init(null);
    }

    public GYSignView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public GYSignView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    public GYSignView setAllowPaint(boolean allowPaint) {
        this.allowPaint = allowPaint;
        return this;
    }

    private int paintColor = Color.parseColor("#ff3f4a57");

    private int paintBackgroundColor = Color.TRANSPARENT;
    /**
     * 画图区域的最大位置
     */
    private float mSmallX = 0, mSmallY = 0, mBigX = 0, mBigY = 0;
    private float mPreX, mPreY;

    private void init(AttributeSet attributeSet) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attributeSet, R.styleable.GYSignView);
        paintWidthPx = typedArray.getDimensionPixelSize(R.styleable.GYSignView_paintWidth, paintWidthPx);
        paintColor = typedArray.getColor(R.styleable.GYSignView_paintColor, paintColor);
        paintBackgroundColor = typedArray.getColor(R.styleable.GYSignView_paintBackgroundColor, paintBackgroundColor);
        typedArray.recycle();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPathPaint.setDither(true);
        mPathPaint.setStyle(Paint.Style.STROKE);
        mPathPaint.setStrokeJoin(Paint.Join.ROUND);//线段结束处的形状
        mPathPaint.setStrokeCap(Paint.Cap.ROUND);//线段开始结束处的形状
        setPaintWidthPx(paintWidthPx);
        setPaintColor(paintColor);
    }

    public GYSignView setPaintWidthPx(int paintWidthPx) {
        this.paintWidthPx = paintWidthPx;
        mPathPaint.setStrokeWidth(paintWidthPx);
        return this;
    }

    public GYSignView setStrokeDp(int strokeDp) {
        return setPaintWidthPx(GYDisplayUtils.dp2px(getContext(), strokeDp));
    }

    public GYSignView setPaintColor(int paintColor) {
        this.paintColor = paintColor;
        mPathPaint.setColor(paintColor);
        return this;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        resetSign();
    }

    private void resetSign() {
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        if (width > 0 && height > 0) {
            painted = false;
            mPath = new Path();
            mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);
            setPaintBackgroundColor(paintBackgroundColor);
        }
    }

    public GYSignView setPaintBackgroundColor(int paintBackgroundColor) {
        this.paintBackgroundColor = paintBackgroundColor;
        mBitmap.eraseColor(this.paintBackgroundColor);
        return this;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        canvas.drawPath(mPath, mPathPaint);
    }

    public Bitmap getBitmap() {
        return mBitmap;
    }

    /**
     * 计算画图区域的位置
     *
     * @param x
     * @param y
     */
    private void computeDrawMaxRang(float x, float y) {
        if (mSmallX == 0 && mSmallY == 0 && mBigX == 0 && mBigY == 0) {
            mSmallX = mBigX = x;
            mBigY = mSmallY = y;
        } else {
            mSmallX = Math.min(mSmallX, x);
            mSmallY = Math.min(mSmallY, y);
            mBigX = Math.max(mBigX, x);
            mBigY = Math.max(mBigY, y);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (allowPaint) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mPreX = event.getX();
                    mPreY = event.getY();
                    computeDrawMaxRang(mPreX, mPreY);
//                mPath.reset();
                    mPath.moveTo(mPreX, mPreY);
                    painted = true;
                    break;
                case MotionEvent.ACTION_MOVE:
                    float x = event.getX();
                    float y = event.getY();
//                computeDrawMaxRang(x, y);
                    //绘制圆滑曲线（贝塞尔曲线）
                    mPath.quadTo(mPreX, mPreY, x, y);
                    mPreX = x;
                    mPreY = y;
                    break;
                case MotionEvent.ACTION_UP:
//                computeDrawMaxRang(event.getX(), event.getY());
                    mPath.lineTo(event.getX(), event.getY());
                    mCanvas.drawPath(mPath, mPathPaint);
                    break;
            }
            invalidate();
            return true;
        }
        return super.onTouchEvent(event);
    }

    public void clear() {
        resetSign();
        invalidate();
    }

    public boolean isPainted() {
        return painted;
    }

    public boolean isAllowPaint() {
        return allowPaint;
    }

    public int getPaintColor() {
        return paintColor;
    }

    public int getPaintWidthPx() {
        return paintWidthPx;
    }
}
